/**
 * Copyright 2007-2010 非也
 * All rights reserved. 
 * 
 * This library is free software; you can redistribute it and/or modify it under the
 * terms of the GNU Lesser General Public License v3 as published by the Free Software
 * Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License along
 * with this library; if not, see http://www.gnu.org/licenses/lgpl.html.
 *
 */
package org.fireflow2.designer.eclipse.properties.service.java;

import org.eclipse.draw2d.ColorConstants;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.core.BinaryType;
import org.eclipse.jdt.internal.core.SourceType;
import org.eclipse.jdt.ui.IJavaElementSearchConstants;
import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.SelectionDialog;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.fireflow.model.servicedef.impl.JavaInterfaceDef;
import org.fireflow.service.java.JavaService;
import org.fireflow2.designer.eclipse.modelwrapper.basic.ServiceDefWrapper;
import org.fireflow2.designer.eclipse.properties.service.AbstractServiceEditPanel;
import org.fireflow2.designer.eclipse.util.Util4Eclipse;

/**
 * 
 * @author 非也 nychen2000@163.com Fire Workflow 官方网站：www.firesoa.com 或者
 *         www.fireflow.org
 * 
 */
public class JavaServiceEditPanel extends AbstractServiceEditPanel {
	/**
	 * @param svcDef
	 */
	public JavaServiceEditPanel(ServiceDefWrapper svcDefWrapper) {
		super(svcDefWrapper);
	}

	public JavaServiceEditPanel(){
		
	}
	Text javaClassFullNameInput = null;

	Button javaSearchButton = null;
	Button radioButton_Java = null;

	Button radioButton_Spring = null;
	Text springBeanIdInput = null;

	Text displayText = null;
	Text descriptionText = null;
	
	IType iType = null;
	
	public IType getIType(){
		if (iType==null){
			IJavaProject jProj = JavaCore.create(getServiceDefWrapper().getProject());
			String javaTypeName = javaClassFullNameInput.getText();
			if (javaTypeName!=null && !javaTypeName.trim().equals("")){
				try {
					iType = jProj.findType(javaTypeName);
				} catch (JavaModelException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			

		}

		return iType;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.fireflow2.designer.eclipse.commands.service.AbstractServiceEditPanel
	 * #createControl(org.eclipse.swt.widgets.Composite)
	 */
	@Override
	public Control createControl(final Composite composite) {
		FormToolkit formToolkit = new FormToolkit(Display.getCurrent());

//		
		GridLayout layout = new GridLayout(3, false);
		composite.setLayout(layout);

		GridData gridData = null;

		// 选择java 类
		radioButton_Java = new Button(composite, SWT.RADIO);
		radioButton_Java.setText("Java类全名：");
		radioButton_Java.setSelection(true);
		radioButton_Java.addSelectionListener(new SelectionAdapter() {

			public void widgetSelected(SelectionEvent e) {
				javaClassFullNameInput.setEnabled(true);
				javaClassFullNameInput.setBackground(ColorConstants.white);
				javaSearchButton.setEnabled(true);
				springBeanIdInput.setEnabled(false);
				springBeanIdInput.setBackground(ColorConstants.button);
				JavaService javaSvc = (JavaService) getServiceDefWrapper().getWorkflowModelElement();
				if (javaSvc!=null){
					javaSvc.setJavaBeanName("");
				}
			}

		});

		javaClassFullNameInput = formToolkit.createText(composite, "");
		gridData = new GridData(GridData.FILL_HORIZONTAL);
		javaClassFullNameInput.setLayoutData(gridData);
		javaClassFullNameInput.setFocus();
		javaClassFullNameInput.addModifyListener(new ModifyListener() {

			public void modifyText(ModifyEvent e) {
				
				boolean isValid = updateServiceProperty("JAVA_CLASS_NAME");
				
				if (isValid){
					String javaClassFullName = javaClassFullNameInput.getText();
					if (displayText.getText()==null || displayText.getText().trim().equals("")){
						displayText.setText("Java类["+javaClassFullName+"]");
					}
					
					if (descriptionText.getText()==null || descriptionText.getText().trim().equals("")){
						descriptionText.setText("Java类["+javaClassFullName+"]");
					}
				}

			}

		});

		
		javaSearchButton = formToolkit.createButton(composite, "查找", SWT.PUSH);
		javaSearchButton.addSelectionListener(new SelectionAdapter(){
			public void widgetSelected(SelectionEvent e) {
				try {
					SelectionDialog selectionDialog = JavaUI.createTypeDialog(
							composite.getShell(), 
							PlatformUI.getWorkbench().getProgressService(),getServiceDefWrapper().getProject() , IJavaElementSearchConstants.CONSIDER_CLASSES, false);
					
					int result = selectionDialog.open();
					if (result==Dialog.OK){
						Object[] objList = selectionDialog.getResult();
						if (objList!=null && objList.length>0){
							Object obj = objList[0];
							if (obj instanceof BinaryType){
								javaClassFullNameInput.setText(((BinaryType)obj).getFullyQualifiedName());
								iType = (BinaryType)obj;
							}else if (obj instanceof SourceType){
								javaClassFullNameInput.setText(((SourceType)obj).getFullyQualifiedName());
								iType = (SourceType)obj;
							}
							
						}
					}

	
//					IJavaProject jProj = JavaCore.create(getServiceDefWrapper().getProject());
//					IType type = jProj.findType(javaClassFullNameInput.getText());
//					System.out.println(type);

//					SearchPattern pattern = SearchPattern.createPattern(javaClassFullNameInput.getText(),
//							IJavaSearchConstants.CLASS,
//							IJavaSearchConstants.DECLARATIONS, 
//							SearchPattern.R_EXACT_MATCH);
//					IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaElement[]{jProj});
//					SearchEngine searchEngine = new SearchEngine();
//					searchEngine.search(pattern, participants, scope, requestor, monitor);
//					searchEngine.searchAllTypeNames(qualifications, typeNames, scope, nameMatchRequestor, waitingPolicy, progressMonitor)
				} catch (JavaModelException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}

			}
		});
		// Spring bean
		radioButton_Spring = new Button(composite, SWT.RADIO);
		radioButton_Spring.setText("Srping Bean：");
		radioButton_Spring.setSelection(false);
		radioButton_Spring.addSelectionListener(new SelectionAdapter() {

			public void widgetSelected(SelectionEvent e) {
				javaClassFullNameInput.setEnabled(false);
				javaClassFullNameInput.setBackground(ColorConstants.button);
				javaSearchButton.setEnabled(false);
				springBeanIdInput.setEnabled(true);
				springBeanIdInput.setBackground(ColorConstants.white);

				JavaService javaSvc = (JavaService) getServiceDefWrapper().getWorkflowModelElement();
				if (javaSvc!=null){
					javaSvc.setJavaClassName("");
				}
				
			}

		});
		springBeanIdInput = formToolkit.createText(composite, "");
		gridData = new GridData(GridData.FILL_HORIZONTAL);
		gridData.horizontalSpan = 2;
		springBeanIdInput.setLayoutData(gridData);
		springBeanIdInput.setEnabled(false);
		springBeanIdInput.setBackground(ColorConstants.button);
		springBeanIdInput.addModifyListener(new ModifyListener() {

			public void modifyText(ModifyEvent e) {
				boolean isValid = updateServiceProperty("JAVA_BEAN_NAME");
				
				if (isValid){
					String beanName = springBeanIdInput.getText();
					if (displayText.getText()==null || displayText.getText().trim().equals("")){
						displayText.setText("Java Bean["+beanName+"]");
					}
					
					if (descriptionText.getText()==null || descriptionText.getText().trim().equals("")){
						descriptionText.setText("Java Bean["+beanName+"]");
					}
				}
			}

		});

		// 名称（自动根据java class name获取）
		// Label nameLb = new Label(composite,SWT.NULL);
		// nameLb.setText("服务标识：");
		// gridData = new GridData(GridData.FILL_HORIZONTAL);
		// gridData.horizontalSpan = 2;
		// Text nameText = formToolkit.createText(composite, "");
		// nameText.setLayoutData(gridData);

		// 中文名称
		Label displayLb = new Label(composite, SWT.NULL);
		displayLb.setText("中文名称：");
		gridData = new GridData(GridData.FILL_HORIZONTAL);
		gridData.horizontalSpan = 2;
		displayText = formToolkit.createText(composite, "");
		displayText.setLayoutData(gridData);
		displayText.addModifyListener(new ModifyListener() {

			public void modifyText(ModifyEvent e) {
				updateServiceProperty("DISPLAY_NAME");
			}

		});

		// 描述
		Label descriptionLb = new Label(composite, SWT.WRAP);
		descriptionLb.setText("描述信息：");
		gridData = new GridData(GridData.FILL_HORIZONTAL
				| GridData.FILL_VERTICAL);
		gridData.horizontalSpan = 2;
		descriptionText = formToolkit.createText(composite, "");
		descriptionText.setLayoutData(gridData);
		descriptionText.addModifyListener(new ModifyListener() {

			public void modifyText(ModifyEvent e) {
				updateServiceProperty("DESCRIPTION");
			}

		});

		return composite;
	}
	
	public void refreshUI(){
		JavaService javaSvc = (JavaService) getServiceDefWrapper().getWorkflowModelElement();
		if (javaSvc!=null){
			String beanName = javaSvc.getJavaBeanName();
			if (beanName!=null && !beanName.trim().equals("")){
				radioButton_Spring.setSelection(true);
				springBeanIdInput.setText(beanName);
			}else{
				String className = javaSvc.getJavaClassName();
				radioButton_Java.setSelection(true);
				javaClassFullNameInput.setText(className==null?"":className);
			}
			displayText.setText(javaSvc.getDisplayName()==null?"":javaSvc.getDisplayName());
			descriptionText.setText(javaSvc.getDescription()==null?"":javaSvc.getDescription());
		}
	}

	protected boolean updateServiceProperty(String propertyName) {
		JavaService javaSvc = (JavaService) this.getServiceDefWrapper().getWorkflowModelElement();
		if (javaSvc == null) {
			return false;
		}
		JavaInterfaceDef _interface = (JavaInterfaceDef)javaSvc.getInterface();
		if (_interface==null){
			_interface = new JavaInterfaceDef();
			javaSvc.setInterface(_interface);
		}

		boolean propertyIsOK = true;
		String errorMessage = null;
		Object newValue = null;
		Object oldValue = null;

		// 检查类名是否合法
		if (propertyName.equals("JAVA_CLASS_NAME")
				&& !Util4Eclipse.strEquals(javaClassFullNameInput.getText(),
						javaSvc.getJavaClassName())) {

			String javaClassFullName = javaClassFullNameInput.getText();
			if (!Util4Eclipse.isValidJavaFullClassName(javaClassFullName)) {
				propertyIsOK = false;
				errorMessage = "Java类名不合法。";
				this.firePropertyModifyEvent(propertyIsOK, errorMessage,
						"JAVA_CLASS_NAME", javaClassFullNameInput.getText(),
						javaSvc.getJavaClassName());
				return propertyIsOK;
			}

			oldValue = javaSvc.getJavaClassName();
			newValue = javaClassFullName;
			propertyIsOK = true;

			javaSvc.setJavaClassName(javaClassFullName);
			_interface.setInterfaceClassName(javaClassFullName);
			// 设置ServiceName
			if (javaClassFullName != null
					&& !javaClassFullName.trim().equals("")) {
				String temp = javaClassFullName;
				if (javaClassFullName.indexOf("$") > 0) {
					temp = javaClassFullName.replace("$", "_");
				}
				int lastIndex = temp.lastIndexOf(".");

				if (lastIndex < 0) {
					javaSvc.setName(temp);
				} else {
					javaSvc.setName(temp.substring(lastIndex + 1));
				}
			}
			
			this.firePropertyModifyEvent(propertyIsOK, errorMessage,
					"JAVA_CLASS_NAME", newValue,
					oldValue);
			return propertyIsOK;
		}


			
		else if (propertyName.equals("JAVA_BEAN_NAME")
				&& !Util4Eclipse.strEquals(springBeanIdInput.getText(),
						javaSvc.getJavaBeanName())) {
			String springBeanFullName = springBeanIdInput.getText();
			if (!Util4Eclipse.isValidJavaFullClassName(springBeanFullName)) {
				propertyIsOK = false;
				errorMessage = "Spring Bean Id不合法。";
				this.firePropertyModifyEvent(propertyIsOK, errorMessage,
						"JAVA_BEAN_NAME", springBeanFullName,
						javaSvc.getJavaBeanName());
				return propertyIsOK;
			}

			oldValue = javaSvc.getJavaBeanName();
			newValue = springBeanFullName;
			propertyIsOK = true;

			javaSvc.setJavaBeanName(springBeanFullName);
			// 设置ServiceName
			if (springBeanFullName != null
					&& !springBeanFullName.trim().equals("")) {
				String temp = springBeanFullName;
				if (springBeanFullName.indexOf("$") > 0) {
					temp = springBeanFullName.replace("$", "_");
				}
				int lastIndex = temp.lastIndexOf(".");

				if (lastIndex < 0) {
					javaSvc.setName(temp);
				} else {
					javaSvc.setName(temp.substring(lastIndex + 1));
				}
			}

			this.firePropertyModifyEvent(propertyIsOK, errorMessage,
					"JAVA_BEAN_NAME", newValue, oldValue);
			return propertyIsOK;
		}


		
		
		else if (propertyName.equals("DISPLAY_NAME") && !Util4Eclipse.strEquals(displayText.getText(), javaSvc.getDisplayName())){
			String displayName = displayText.getText();

			oldValue = javaSvc.getDisplayName();
			newValue = displayName;
			propertyIsOK = true;
			javaSvc.setDisplayName(displayName);
			
			this.firePropertyModifyEvent(propertyIsOK, errorMessage,
					"DISPLAY_NAME", newValue, oldValue);
			return propertyIsOK;
		}
		
		else if (propertyName.equals("DESCRIPTION") && !Util4Eclipse.strEquals(descriptionText.getText(), javaSvc.getDescription())){

			oldValue = javaSvc.getDescription();
			newValue = descriptionText.getText();
			propertyIsOK = true;
			
			javaSvc.setDescription(descriptionText.getText());
			
			this.firePropertyModifyEvent(propertyIsOK, errorMessage,
					"DISPLAY_NAME", newValue, oldValue);
			return propertyIsOK;
		}
		return false;

	}

}
